#include <assert.h>
#include <pthread.h>

#include "apue.h"

pthread_t tid1, tid2;
int count = 0; /* 共享变量 */

pthread_cond_t qready = PTHREAD_COND_INITIALIZER;
pthread_mutex_t qlock = PTHREAD_MUTEX_INITIALIZER;

void *process_msg(void *arg)
{
  char tag[5] = {'\0'};
  int get_count = 0;

  // 获取进程标识
  if (pthread_equal(pthread_self(), tid1)) {
    strcpy(tag, "tid1");
  } else {
    strcpy(tag, "tid2");
  }

  printf("%s start.\n", tag);
  for (;;) {
    pthread_mutex_lock(&qlock);
    while (count <= 0) {
      printf("%s wait msg\n", tag);
      pthread_cond_wait(&qready, &qlock);
    }
    count--;
    get_count++;
    // printf("0x%lx get count, now is %d\n", (unsigned long)pthread_self(), count);
    pthread_mutex_unlock(&qlock);
    /* 处理消息 */
    printf("%s get count:%d\n", tag, get_count);
    // 放弃cpu，让另一个处理进场有机会得到数据
    sleep(1);
  }
  return NULL;
}

int main(void)
{
  int err;
  void *tret;

  err = pthread_create(&tid1, NULL, process_msg, NULL);
  assert(!err);

  err = pthread_create(&tid2, NULL, process_msg, NULL);
  assert(!err);

  sleep(1);

  for (;;) {
    pthread_mutex_lock(&qlock);
    count += 4;
    printf("add count to %d\n", count);
    pthread_mutex_unlock(&qlock);
    // 测试两种唤醒方式
#if 1
    pthread_cond_broadcast(&qready);
#else
    pthread_cond_signal(&qready);
#endif
    // 保证两个进程都可以有时间处理数据
    sleep(3);
  }
  return 0;
}